package com.beidu.lottery.call.utils.concurrent;

import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Supplier;

/**
 * 可重入锁工具类
 * <p>
 * 使用ReentrantLock实现线程同步(非阻塞式锁,基于AQS实现), 如需分布式锁请使用RedissonClient等.
 *
 * @author huangzhiao
 */
@Component
@SuppressWarnings("unused")
public class ReentrantLockUtil {

    /**
     * ReentrantLock对象Map，用于实现线程同步
     */
    private final Map<String, ReentrantLock> locks = new ConcurrentHashMap<>();

    /**
     * 该方法接受一个Supplier对象作为参数，用于执行有返回值的函数
     *
     * @param key      键
     * @param supplier 函数
     * @param <T>      数据泛型
     * @author 北渡
     */
    public <T> T executeWithLock(String key, Supplier<T> supplier) {
        ReentrantLock lock = locks.computeIfAbsent(key, k -> new ReentrantLock());
        try {
            lock.lock();
            return supplier.get();
        } finally {
            lock.unlock();
        }
    }

}
